package nayasis.common.ui.javaFx;

import java.io.IOException;
import java.net.URL;

import javafx.fxml.FXMLLoader;
import javafx.fxml.LoadException;
import javafx.scene.layout.Pane;
import nayasis.common.log.NLogger;
import nayasis.common.util.ClassUtil;

public abstract class GuiUtil {

	/**
	 * Self Class Name
	 */
	private final static String thisClassName = GuiUtil.class.getName();
	
	/**
	 * FXML 파일을 읽어 GUI 화면 Layout을 만든다.
	 * 
	 * <pre>
	 * 
	 * AnchorPane page = GuiUtil.getAnchorPane( getClass().getResource("PersonTable.fxml"), new Controller() );
	 * 
	 * </pre>
	 * 
	 * @param url
	 * @param controller
	 * @return
	 * @throws IOException
	 */
	public static Pane getPane( URL url ) throws IOException {
		
		FXMLLoader fxmlLoader = new FXMLLoader();

		fxmlLoader.setLocation( url );
		
		Pane pane = null;
		
		try {
			pane = (Pane) fxmlLoader.load();
			
		} catch ( LoadException e ) {
			fxmlLoader.setController( null );
			pane = (Pane) fxmlLoader.load();
			NLogger.debug.println( e );
		}
		
		return pane;
		
	}

	/**
	 * FXML 파일을 읽어 GUI 화면 Layout을 만든다.
	 * 
	 * <pre>
	 * 
	 * AnchorPane page = GuiUtil.getAnchorPane( getClass().getResource("PersonTable.fxml"), new Controller() );
	 * 
	 * </pre>
	 * 
	 * @param url
	 * @param controller
	 * @return
	 * @throws IOException
	 */
	public static Pane getPane( URL url, Object controller ) throws IOException {
		
		FXMLLoader fxmlLoader = new FXMLLoader();
		
		fxmlLoader.setLocation( url );
		
		fxmlLoader.setController( controller );
		
		Pane pane = null;
		
		try {
			pane = (Pane) fxmlLoader.load();
			
		} catch ( LoadException e ) {
			fxmlLoader.setController( null );
			pane = (Pane) fxmlLoader.load();
			NLogger.debug.println( e );
		}
		
		return pane;
		
	}

	/**
	 * 동일 패키지 내에 존재하는 FXML 파일을 읽어 GUI 화면 Layout을 만든다. 
	 * 
	 * @param fxmlFileName
	 * @param controller
	 * @return
	 * @throws IOException
	 */
	public static Pane getPane( String fxmlFileName ) throws IOException {
		
		Class<?> callerClass = getCallerClass();
		
		URL url = callerClass.getResource( fxmlFileName );
		
		return getPane( url );
		
	}

	/**
	 * 동일 패키지 내에 존재하는 FXML 파일을 읽어 GUI 화면 Layout을 만든다. 
	 * 
	 * @param fxmlFileName
	 * @param controller
	 * @return
	 * @throws IOException
	 */
	public static Pane getPane( String fxmlFileName, Object controller ) throws IOException {
		
		Class<?> callerClass = getCallerClass();
		
		URL url = callerClass.getResource( fxmlFileName );
		
		return getPane( url, controller  );
		
	}

	private static Class<?> getCallerClass() {

		StackTraceElement stackTrace = getStackTrace();
		
		@SuppressWarnings("rawtypes")
		Class callerClass = null;
		try {
			callerClass = ClassUtil.getClass( stackTrace.getClassName() );
		} catch ( ClassNotFoundException e ) {
			e.printStackTrace();
		}

		return callerClass;
	
	}
	
	/**
	 * 호출된 지점의 StackTrace 정보를 가져온다.
	 *
	 * @return StackTrace 정보
	 */
	private static StackTraceElement getStackTrace() {

		StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();

		StackTraceElement stackForLogger = null;

		boolean watchStart = false;

		for( int i = 0, iCnt = stackTraceElements.length; i < iCnt; i++ ) {

			StackTraceElement stack = stackTraceElements[ i ];

			if( watchStart == false && ! thisClassName.equals(stack.getClassName()) ) {
				continue;

			} else if( watchStart == true && ! thisClassName.equals(stack.getClassName()) ) {
				stackForLogger = stack;
				break;

			} else {
				watchStart = true;
			}

		}

		return stackForLogger;

	}
	
}
